package cn.com.doone.common.uc.oauth.shiro;

import java.util.Calendar;
import java.util.Map;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.springframework.beans.factory.annotation.Autowired;

import cn.com.doone.common.uc.infrastructure.jdbc.OauthJdbcRepository;
import cn.com.doone.common.uc.infrastructure.ldap.OauthLdapRepository;
import cn.com.doone.common.uc.utils.ApiSign;
import cn.com.doone.common.uc.utils.DES3;
import cn.com.doone.common.uc.utils.PasswordUtils;
import cn.com.doone.common.uc.utils.PropertiesUtils;

public class DooneCredentialsMatcher extends SimpleCredentialsMatcher {
	
	@Autowired
	private OauthJdbcRepository oauthJdbcRepository;
	
	@Autowired
	private OauthLdapRepository oauthLdapRepository;
	
	@Autowired
	private PropertiesUtils propertiesUtils;
	
	@Override  
    public boolean doCredentialsMatch(AuthenticationToken token,  AuthenticationInfo info) {  
		try {
			String userAccount = token.getPrincipal().toString();
			String password = toString(token.getCredentials());
			
//			Calendar cal = Calendar.getInstance();
//			int year = cal.get(Calendar.YEAR);
			
//			password = DES3.decode(password, "ZGJMWQJSTMDZQQRDOONE" + String.valueOf(year));
			
			Map<String, Object> userMap = oauthJdbcRepository.findUserInfoByUserAccount(userAccount);
			
			String tempStaffId = (String) userMap.get("TEMP_STAFF_ID");
			String encryptionType = (String) userMap.get("ENCRYPTION_TYPE");
			
			if (tempStaffId == null) {
				tempStaffId = "";
			}
			
			Object tokenCredentials = null;
			
			if (encryptionType.equals("1")) {
				tokenCredentials = PasswordUtils.md5Password(tempStaffId + password);
			} else if (encryptionType.equals("2")) {
				tokenCredentials = PasswordUtils.openLdapMD5(password);
			} else if (encryptionType.equals("3")) {
				tokenCredentials = ApiSign.md5(ApiSign.md5(password, "UTF-8") + tempStaffId, "UTF-8");
			}
			
	        Object accountCredentials = getCredentials(info);
	        
	        boolean isEquals = equals(tokenCredentials, accountCredentials);
	        
	        if (isEquals) {
	        	if (encryptionType.equals("1") || encryptionType.equals("3")) {
	        		oauthJdbcRepository.changePassword(userAccount, PasswordUtils.openLdapMD5(password),DES3.encode(password, propertiesUtils.getSecretKey()));
	        		
	        		if (propertiesUtils.isLdapEnable()) {
	        			oauthLdapRepository.changePassword(userAccount, PasswordUtils.openLdapMD5(password));
	        		}
	        		
	        	}
	        	
	        }
	        
	        return isEquals;  
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
    }
	
	/**
	 * 以下都是同步LDAP数据的方法
	 */
	
	/*public static void main(String [] args) throws NamingException {
			
		LdapContext ldapContext = getContext();
		// searchOU(ldapContext);
		// searchUserByOU(ldapContext);
		// addUser(ldapContext, "test9", "1q2w3E4R", "OU=新东网科技,DC=doone,DC=com,DC=cn", "士大夫");
		// updateUser(ldapContext, "test2", "OU=租户一,DC=doone,DC=com,DC=cn");
		// deleteUser(ldapContext, "test2", "OU=租户一,DC=doone,DC=com,DC=cn");
		// updatePassword(ldapContext, "test3", "1q2w3E4R", "OU=租户一,DC=doone,DC=com,DC=cn");;
		// addOU(ldapContext, "租户二", "DC=doone,DC=com,DC=cn");
		// deleteOU(ldapContext, "租户二", "DC=doone,DC=com,DC=cn");
		
	}
	private static void addUser(LdapContext ldapContext, String userName, String password, String dn, String realname, String userInfoId) throws Exception {
	
			String distinguishedName = "CN=" + userName + "," + dn;   
            Attributes newAttributes = new BasicAttributes(true);   
            Attribute oc = new BasicAttribute("objectClass");
            
            oc.add("top");   
            oc.add("account");
            oc.add("xdwAccount");
            newAttributes.put(oc);   
            newAttributes.put(new BasicAttribute("uid", userName));   
            newAttributes.put(new BasicAttribute("dbid", userInfoId));   
            newAttributes.put(new BasicAttribute("displayName", realname));
            newAttributes.put(new BasicAttribute("realname", realname));
            newAttributes.put(new BasicAttribute("userPassword", PasswordUtils.openLdapMD5("123456a@")));
            newAttributes.put(new BasicAttribute("ou", "doone.com.cn"));
            newAttributes.put(new BasicAttribute("status", "1"));
            
            String updateTime = com.doone.common.uc.utils.LdapUtils.Timestamp2generalized(new Timestamp(System.currentTimeMillis()), TimeZone.getTimeZone("CST"));
            
            newAttributes.put(new BasicAttribute("updateTime", updateTime));
            ldapContext.createSubcontext(distinguishedName, newAttributes);
		

	}
	
	private static LdapContext getContext() throws NamingException {
		
		Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
		ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		// ldapEnv.put(Context.PROVIDER_URL,  "ldap://192.168.100.133:389");
		ldapEnv.put(Context.PROVIDER_URL,  "ldap://192.168.100.32:389");
		// ldapEnv.put(Context.PROVIDER_URL, "ldaps://192.168.100.70:636");
		ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
		ldapEnv.put(Context.SECURITY_PRINCIPAL, "cn=Users,dc=doone,dc=com,dc=cn");
		// ldapEnv.put(Context.SECURITY_PRINCIPAL, "root");
		ldapEnv.put(Context.SECURITY_CREDENTIALS, "xiE7usWA");
		// ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
		// ldapEnv.put(Context.REFERRAL, "follow");
		
		return new InitialLdapContext(ldapEnv, null);
	}*/
	
}
